package com.lyy.polymorphic.detail;


/**
 * @Author: GZQ
 * @date: 2024/11/17 21:54
 * @description: 多态的注意事项和细节讨论
 */

public class PolyDetail {

    /*
     * 多态的前提是：两个对象(类)存在继承关系
     * 多态的向上转型
     * 1. 本质：父类的引用指向了子类的对象
     * 2. 语法：父类类型 引用名 = new 子类类型();
     * 3. 特点：编译类型看左边, 运行类型看右边。
     * 可以调用父类中的所有成员(需遵守访问权限)，
     * 不能调用子类中特有成员;
     * 最终运行效果看子类的具体实现
     *
     * 多态的向下转型
     * 1. 语法： 子类类型  引用名 = (子类类型) 父类引用;
     * 2. 只能强转父类的引用, 不能强转父类的对象;
     * 3. 要求父类引用必须指向的是当前目标类型的对象
     * 4. 可以调用子类类型中所有的成员
     * */

    public static void main(String[] args) {

        // 向上转型：父类的引用指向了子类的对象
        // 语法：父类类型 引用名 = new 子类类型();
        Animal animal = new Cat();
        Object object = new Cat();// 可以吗？ --> 可以，因为Object是所有类的父类，所有类都可以向上转型为Object类型

        // 向上转型调用方法的规则如下:
        // (1)可以调用父类中所有成员(需遵守访问权限)
        // (2)但是不能调用子类特有的成员
        // (3)因为在编译阶段，能调用哪些成员，是由编译类型来决定的
        //animal.catchMouse(); 错误 --> 编译类型是Animal，没有catchMouse方法
        // (4)最终的运行效果看子类的具体实现,调用方法时,按照从子类(运行类型)开始查找方法
        // 然后调用, 规则和方法调用规则一致。
        animal.eat();// 猫吃鱼
        animal.run();// 跑
        animal.sleep();// 睡
        animal.show(); // hello, 你好


        // 目的为了：能调用Cat的 catchMouse方法
        // 多态的向下转型
        // (1)语法：子类类型  引用名 = (子类类型) 父类引用;

        Cat cat = (Cat) animal; // 编译类型是 Cat, 运行类型是 Cat
        cat.catchMouse();
        // (2)要求父类的引用必须指向的是当前目标类型的对象
      //  Dog dog = (Dog) animal; // 错误 --> 运行类型是Cat，不可转换为Dog

        System.out.println("ok~~~");

    }
}